﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Futajma.MigrationStudio.GenericPersistance.Data
{
    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class TemplateDefinition
    {
        [XmlIgnore]
        static TemplateDefinition _templateDefinition = null;
        [XmlIgnore]
        public static TemplateDefinition Instance
        {
            get
            {
                if (_templateDefinition == null)
                {
                    _templateDefinition = new TemplateDefinition();
                }
                return _templateDefinition;
            }
        }

        [XmlArray("SiteCollectionDefinitions")]
        [XmlArrayItem("SiteCollectionDefinition")]
        public List<SiteCollectionTemplate> SiteCollectionDefinitions { get; set; }

        [XmlIgnore]
        public Dictionary<Guid, Template> TemplateDictionary { get; private set; }

        public Template GetTemplate(Guid id)
        {
            if (TemplateDictionary.ContainsKey(id))
            {
                return TemplateDictionary[id];
            }
            else
            {
                return null;
            }
        }

        TemplateDefinition()
        {
            TemplateDictionary = new Dictionary<Guid, Template>();
            SiteCollectionDefinitions = new List<SiteCollectionTemplate>();
        }

        public void Clear()
        {
            TemplateDictionary.Clear();
            SiteCollectionDefinitions.Clear();
        }

        #region Load/Save Methods
        public static List<SiteCollectionTemplate> LoadXml(Stream stream)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<SiteCollectionTemplate>));
            var sitecollectionTemplate = (List<SiteCollectionTemplate>)(serializer.Deserialize(stream));
            return sitecollectionTemplate;
        }

        public static StringBuilder Save(List<SiteCollectionTemplate> sitecollectionTemplate)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UnicodeEncoding(false, false);
            settings.Indent = true;
            settings.OmitXmlDeclaration = true;

            var serializer = new XmlSerializer(typeof(List<SiteCollectionTemplate>));
            StringBuilder sb = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(sb, settings))
            {
                serializer.Serialize(writer, sitecollectionTemplate);
            }
            return sb;
        }
        #endregion

    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class SiteCollectionTemplate : Template
    {
        public SiteCollectionTemplate()
        {
            EnterpriseMetaDatas = new List<MetaData>();
            SiteTemplates = new List<SiteTemplate>();
        }

        public SiteTemplate RootSiteTemplate { get; set; }

        [XmlArray("EnterpriseMetaDatas")]
        [XmlArrayItem("EnterpriseMetaData")]
        public List<MetaData> EnterpriseMetaDatas { get; set; }

        [XmlArray("SiteTemplates")]
        [XmlArrayItem("SiteTemplate")]
        public List<SiteTemplate> SiteTemplates { get; set; }
    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class SiteTemplate : SubTemplate
    {
        [XmlArray("LibraryTemplates")]
        [XmlArrayItem("LibraryTemplate")]
        public List<LibraryTemplate> LibraryTemplates { get; set; }

        [XmlArray("SiteTemplates")]
        [XmlArrayItem("SiteTemplate")]
        public List<SiteTemplate> SiteTemplates { get; set; }

        public SiteTemplate()
        {
            LibraryTemplates = new List<LibraryTemplate>();
            SiteTemplates = new List<SiteTemplate>();
        }
    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class LibraryTemplate : SubTemplate
    {
        public LibraryTemplate()
        {
            MetaDatas = new List<MetaData>();
        }

        public bool CreateFolderAllowed { get; set; }

        [XmlArray("MetaDatas")]
        [XmlArrayItem("MetaData")]
        public List<MetaData> MetaDatas { get; set; }

        [XmlArray("Folders")]
        [XmlArrayItem("Folder")]
        public List<Folder> Folders { get; set; }
    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class SubTemplate : Template
    {
        public bool CreateAsDefault { get; set; }
        public bool NotShownAsCreateNewLibrary { get; set; }
        //public bool Convertable { get; set; }
    }

    [System.Xml.Serialization.XmlInclude(typeof(SiteCollectionTemplate))]
    [System.Xml.Serialization.XmlInclude(typeof(SiteTemplate))]
    [System.Xml.Serialization.XmlInclude(typeof(LibraryTemplate))]
    [System.Xml.Serialization.XmlInclude(typeof(MetaData))]
    [System.Xml.Serialization.XmlInclude(typeof(Folder))]
    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class Template
    {

        Guid _id = Guid.Empty;

        public string Name { get; set; }

        //[XmlIgnore]
        public Guid ID
        {
            get { return _id; }
            set
            {
                _id = value;
                TemplateDefinition.Instance.TemplateDictionary.Add(_id, this);
            }
        }

        //public string Identifier { get; set; }
        //public string TemplateName { get; set; }
    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class Folder : Template
    {
        [XmlArray("Folders")]
        [XmlArrayItem("Folder")]
        public List<Folder> Folders { get; set; }
    }

    [ObfuscationAttribute(Exclude = true, ApplyToMembers = true)]
    public class MetaData : Template
    {
        public string Value { get; set; }
    }
}
